<!--
  工作流组件，包含工作流的基本功能

  示例：
    <qm-workflow
      :rules="rules"
      keyProp="leaveId"
      :categories="['身份证（正反面）', '医生诊断证明']"
    >
      <template v-slot:form="{ model }">
        <el-row :gutter="12">
          <el-col :span="12">
            <el-form-item label="申请人：" prop="applyUserName">
              <el-input v-model="model.applyUserName" placeholder="请输入内容"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="申请时间：" prop="applyTime">
              <el-date-picker
                v-model="model.applyTime"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择日期"
              ></el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>
      </template>
    </qm-workflow>

  说明：

    rules：表单检验规则，对组件内置的表单做检验

    keyProp：主键属性，不支持多主键

    categories：业务相关的附件类型

-->
<template>
  <div class="qm-workflow">
    <el-row>
      <el-col :span="8">
        <div class="qm-workflow-title">
          <span
            v-text="controlData.workflow.appName"
            style="font-size: 20px; font-weight: bolder"
          ></span>
          -
          <span v-text="controlData.workflow.taskName"></span>
        </div>
      </el-col>
    </el-row>

    <div class="qm-workflow-content">
      <el-form
        class="qm-workflow-content-form"
        label-position="right"
        label-width="100px"
        :ref="formRef"
        :model="models"
        :rules="rules"
        :disabled="
          pageAction === 'view' ||
          controlData.workflow.isFormReadOnly ||
          formDisabled
        "
      >
        <el-tabs :type="tabStyle">
          <slot
            name="before-form"
            v-bind:model="models.model"
            v-bind:models="models"
            v-bind:controlData="controlData"
            v-bind:pageAction="pageAction"
          ></slot>
          <el-tab-pane :label="formTitle">
            <slot
              name="form"
              v-bind:model="models.model"
              v-bind:models="models"
              v-bind:controlData="controlData"
              v-bind:pageAction="pageAction"
            ></slot>
          </el-tab-pane>
          <slot
            name="after-form"
            v-bind:model="models.model"
            v-bind:models="models"
            v-bind:controlData="controlData"
            v-bind:pageAction="pageAction"
          ></slot>
          <el-tab-pane label="附件" v-if="showAttachment">
            <qm-uploader
              :dataKey="models.model[keyProp]"
              :categories="categories"
              :isShowUpload="isShowUpload"
              :uploadFiles="uploadFiles"
              @loaded="allLoaded"
            ></qm-uploader>
          </el-tab-pane>
          <el-tab-pane label="办理记录" v-if="showHistory">
            <qm-table
              :data="{ data: controlData.workflow.history }"
              :showMenu="false"
              :showCheckbox="false"
              :showPager="false"
              :showToolbar="false"
            >
              <qm-table-column field="taskName">环节名称</qm-table-column>
              <qm-table-column field="senderName">发送人</qm-table-column>
              <qm-table-column field="assigneeName">接收人</qm-table-column>
              <qm-table-column field="handlerName">处理人</qm-table-column>
              <qm-table-column field="startTime">接收时间</qm-table-column>
              <qm-table-column field="finishTime">处理时间</qm-table-column>
              <qm-table-column field="opinionText">审批意见</qm-table-column>
            </qm-table>
          </el-tab-pane>
        </el-tabs>
      </el-form>
    </div>

    <div class="qm-workflow-toolbar">
      <div class="modal-bottom-footer">
        <!-- <el-button type="primary" @click="imgModalVisible = true">
          <i class="far fa-map"></i> 流程图
        </el-button> -->
        <el-button type="primary" @click="processGuide">
          <i class="far fa-map"></i> 流程指南
        </el-button>
        <el-button
          type="primary"
          v-if="pageAction !== 'create'"
          @click="selectUserNotify = true"
        >
          <i class="far fa-clone"></i> 传阅
        </el-button>
        <el-button
          type="primary"
          v-if="controlData.workflow.isNotice"
          @click="processNotify"
        >
          <i class="far fa-sticky-note"></i> 已阅
        </el-button>
        <el-button type="danger" v-if="canDelete" @click="processDelete">
          <i class="far fa-trash-alt"></i> 删除
        </el-button>
        <el-button
          type="warning"
          v-if="pageAction === 'edit'"
          @click="processTerminate"
        >
          <i class="far fa-times-circle"></i> 终止
        </el-button>
        <el-button
          type="primary"
          v-if="pageAction === 'edit' && !controlData.workflow.isFirstTask"
          @click="processBackward"
        >
          <i class="far fa-arrow-alt-circle-left"></i> 退回
        </el-button>
        <el-button
          type="primary"
          v-if="
            pageAction === 'view' && !controlData.workflow.isNotice && canUndo
          "
          @click="processRollback"
        >
          <i class="fas fa-undo-alt"></i> 撤回
        </el-button>
        <el-button
          type="primary"
          @click="processSave(formRef)"
          v-if="
            pageAction !== 'view' &&
            !controlData.workflow.isFormReadOnly &&
            !formDisabled
          "
        >
          <i class="far fa-save"></i> 保存
        </el-button>
        <el-button
          type="primary"
          v-if="pageAction !== 'view' && !formDisabled"
          @click="processSend(formRef)"
        >
          <i class="far fa-envelope-open"></i> 下一步
        </el-button>
      </div>
    </div>

    <vxe-modal
      class="qm-workflow-process-img"
      ref="imgModal"
      v-model="imgModalVisible"
      :resize="true"
      width="900px"
      height="500px"
      title="流程图"
    >
      <img v-if="imgModalVisible" :src="processImgUrl" />
    </vxe-modal>

    <qm-workflow-select-user
      v-model="sendDialog.dialogVisible"
      :url="selectUserUrl"
      :params="selectUserModels"
      :needChoose="controlData.workflow.needChoose"
      @select-done="doSend"
      :pageAction="pageAction"
    ></qm-workflow-select-user>

    <common-select
      v-model="selectUserNotify"
      selectKey="selectUsers"
      selectMode="1"
      @success="processDoNotify"
    ></common-select>
  </div>
</template>

<script>
import _ from "lodash";
import QmUploader from "@/libs/components/qm-uploader";
import CommonSelect from "@/views/commonSelect/list";
import QmWorkflowSelectUser from "./qm-workflow-select-user";
import request from "@/utils/request";

export default {
  name: "qm-workflow",
  components: {
    QmUploader,
    CommonSelect,
    QmWorkflowSelectUser,
  },
  inject: ["pageVue"],
  props: {
    // 主键属性，不支持多主键
    keyProp: {
      type: String,
      required: true,
    },
    // 表单检验规则，对组件内置的表单做检验
    rules: {
      type: Object,
      default: () => {},
    },
    // 和业务相关的附件类型
    categories: {
      type: Array,
      default: () => [],
    },
    // 是否显示附件
    showAttachment: {
      type: Boolean,
      default: true,
    },
    // 是否显示办理记录
    showHistory: {
      type: Boolean,
      default: true,
    },
    // 选项卡风格，可选值：card、border-card
    tabStyle: {
      type: String,
      default: "",
    },
    // 表单标题
    formTitle: {
      type: String,
      default: "表单",
    },
    // 内置的 el-form 的 ref 值，一般不用修改
    formRef: {
      type: String,
      default: "qmWorkflowContentForm",
    },
  },
  data() {
    return {
      selectUserNotify: false,
      imgModalVisible: false,
      choicesOptions: [],
      commentOptions: [],
      sendDialog: {
        sendComment: "",
        selectComment: "",
        dialogVisible: false,
        callback: undefined,
        loading: false,
      },
      uploadFiles: [],
      selectUserUrl: "",
      formDisabled: false
    };
  },
  computed: {
    models() {
      return this.getParent().models;
    },
    controlData() {
      return this.getParent().controlData;
    },
    urls() {
      return this.getParent().urls;
    },
    pageAction() {
      return this.getParent().pageAction;
    },
    isShowUpload() {
      return (
        this.controlData.workflow.isFirstTask && this.pageAction !== "view"
      );
    },
    canUndo() {
      let history = this.controlData.workflow.history || [];
      return (
        history.length > 0 &&
        history[history.length - 1].senderId ==
          this.controlData.currentUser.userId
      );
    },
    canDelete() {
      return (
        this.pageAction === "edit" &&
        (this.controlData.workflow.history || []).length === 1
      );
    },
    isNew() {
      return this.pageAction === "create";
    },
    // selectUserUrl() {
    //   return this.appendWorkflowArgs(this.urls.selectUser);
    // },
    selectUserModels() {
      return _.extend({}, this.models, { pageAction: this.pageAction });
    },
    processImgUrl(){
      if (!(!this.urls || !this.controlData || !this.controlData.workflow)) {
        return `${process.env.VUE_APP_BASE_API}${this.urls.processTrace}?appCode=${this.controlData.workflow.appCode}`;
      }
      return "";
    }
  },

  methods: {
    getParent() {
      if (this.pageVue) {
        return this.pageVue;
      }
      console.error(
        "该vue页面没有继承workflowController.js，qm-workflow组件的一些功能可能有异常！"
      );
      return this.$parent;
    },
    done() {
      this.getParent().$emit("done");
    },
    allLoaded() {
      this.getParent().pageLoadDone();
    },

    appendWorkflowArgs(url) {
      let args = {
        appCode: this.controlData.workflow.appCode,
        version: this.controlData.workflow.version,
        taskId: this.controlData.workflow.taskId,
      };
      for (let o in args) {
        if (!args[o]) continue;
        let joinChar = url.indexOf("?") == -1 ? "?" : "&";
        url += joinChar;
        url += o + "=" + args[o];
      }
      return url;
    },

    addAttachment() {
      if (this.isNew) {
        this.models.attachments = [];
        this.uploadFiles.forEach((file) => {
          this.models.attachments.push({ attachmentId: file.attachmentId });
        });
      }
    },

    doValidate(formName) {
      return this.$refs[formName].validate();
    },
    formValidate(forms, idx, rs, rj) {
      this.doValidate(forms[idx])
        .then((valid) => {
          if (valid) {
            if (forms.length - 1 === idx) {
              rs(true);
            } else {
              this.formValidate(forms, idx + 1, rs, rj);
            }
          } else {
            rj(false);
          }
        })
        .catch((e) => {
          this.notifyError("表单检验不通过，请检查表单");
        });
    },
    validate(formNames) {
      let forms = formNames.split(",");
      return new Promise((rs, rj) => {
        this.formValidate(forms, 0, rs, rj);
      });
    },

    processSave(formName) {
      let isNew = this.isNew;
      this.validate(formName)
        .then((valid) => {
          if (valid) {
            this.addAttachment();
            this.getParent()
              .processSave()
              .then((r) => {
                // this.done();
                if (isNew) {
                  // 新增的时候，在保存之后重新设置选人url
                  this.selectUserUrl = this.appendWorkflowArgs(
                    this.urls.selectUser
                  );
                }
              });
          } else {
            console.log("error submit!!");
            return false;
          }
        })
        .catch(() => {
          this.notifyError("表单检验不通过，请检查表单");
        });
    },
    processSend(formName) {
      this.validate(formName)
        .then((valid) => {
          if (valid) {
            if (
              !this.controlData.workflow.needChoose &&
              this.controlData.workflow.isFirstTask
            ) {
              this.addAttachment();
              // 发送
              this.getParent()
                .processSave(undefined, undefined, true)
                .then((r) => {
                  // 发送之后设为只读
                  this.formDisabled = true;
                  this.done();
                });
            } else {
              // 选人
              this.sendDialog.dialogVisible = true;
            }
          } else {
            console.log("error submit!!");
            return false;
          }
        })
        .catch(() => {
          this.notifyError("表单检验不通过，请检查表单");
        });
    },

    doSend({ choices, selectComment, sendComment }) {
      if (this.controlData.workflow.needChoose) {
        if (choices.length == 0) {
          this.$message.warning("请选择处理人！");
          return;
        }
        if (choices.length > 1) {
          this.$message.warning("只能选择一个处理环节！");
          return;
        }
      }
      if (!sendComment) {
        this.$message.warning("请填写处理意见！");
        return;
      }

      let postModel = this.models;
      postModel.pageAction = this.pageAction;
      postModel.workflowComment = sendComment;
      if (choices && choices.length && this.controlData.workflow.needChoose) {
        postModel.choice = choices[0];
      }

      this.addAttachment();
      this.getParent()
        .processSave(this.models, undefined, true)
        .then((r) => {
          if (r.success) {
            this.sendDialog.dialogVisible = false;
            // 发送之后设为只读
            this.formDisabled = true;
            this.done();
          }
        });
    },
    processNotify() {
      this.getParent()
        .processNotify()
        .then((r) => {
          this.done();
        });
    },
    processDoNotify(users) {
      this.selectUserNotify = false;
      this.getParent()
        .processDoNotify(users)
        .then((r) => {
          // this.done();
        });
    },

    processDelete() {
      this.getParent()
        .processDelete()
        .then((r) => {
          this.done();
        });
    },

    processTerminate() {
      this.getParent()
        .processTerminate()
        .then((r) => {
          this.done();
        });
    },

    processRollback() {
      this.getParent()
        .processRollback()
        .then((r) => {
          this.done();
        });
    },

    processBackward() {
      this.getParent()
        .processBackward()
        .then((r) => {
          this.done();
        });
    },
    async processGuide() {
      const res = await request.post("/workflow/serviceGuide/getEntityByCode", {
        code: this.controlData.workflow.appCode,
        pageAction: "view",
      });
      if (!res || res.initMessage) {
        this.imgModalVisible = true;
      } else {
        this.$root.openModal(
          "/workflow/serviceGuide/view",
          {
            workflow: this.controlData.workflow,
            viewModel: res,
            models: res.models,
          },
          "85%",
          "90%",
          { title: "流程指南" }
        );
      }
    }
  },
  created() {
    this.selectUserUrl = this.appendWorkflowArgs(this.urls.selectUser);
  },
};
</script>

<style scoped lang="scss">
.modal-bottom-footer {
  padding: 10px 10px 10px 10px;
}
.qm-workflow-title {
  padding: 5px 0;
}
.qm-workflow-toolbar {
  text-align: right;
}
.qm-workflow-content {
  margin-top: 16px;
}
.qm-workflow-select-user-form {
  padding: 6px;
}
</style>
